from typing import Generic, Optional, Sequence

from pydantic import BaseModel, Field

from app.core.generic_types import OutSchemaType

class PageModel(BaseModel, Generic[OutSchemaType]):
    """分页模型"""

    current_page: int = Field(default=1, description="当前页")
    total_pages: int = Field(description="总页数")
    page_size: int = Field(default=100, description="页面大小")
    total: int = Field(description="数据总数")
    items: Sequence[OutSchemaType] | None = Field(description="当前页数据列表")


class ResultModelBase(BaseModel):
    """基础响应模型"""

    is_success: bool
    code: int
    message: str = ""


class ResultModel(ResultModelBase, Generic[OutSchemaType]):
    """带数据的响应模型"""

    data: Optional[
        OutSchemaType | Sequence[OutSchemaType] | PageModel[OutSchemaType] | bool | str
        ] = None


class ResultFormat:
    @classmethod
    def result_list_model(
        cls,
        *,
        data: Optional[Sequence[OutSchemaType]] = None,
        success_message: str = "成功",
        error_message: str = "没有找到任何数据",
        code: int = 200,
    ) -> ResultModel[Sequence[OutSchemaType]]:
        if data is not None and len(data) > 0:
            return cls.success(code=code, message=success_message, data=data)
        else:
            return cls.error(message=error_message)

    @classmethod
    def result_page_model(
        cls,
        *,
        data: Optional[PageModel[OutSchemaType]] = None,
        success_message: str = "成功",
        error_message: str = "没有找到任何数据",
        code: int = 200,
    ) -> ResultModel[PageModel[OutSchemaType]]:
        if data.items is not None and len(data.items) > 0:
            return cls.success(code=code, message=success_message, data=data)
        else:
            return cls.error(message=error_message)

    @classmethod
    def result_model(
        cls, *, data: Optional[OutSchemaType] = None, model_name: str = "", code: int = 200
    ) -> ResultModel[OutSchemaType]:
        if data is not None:
            return cls.success(code=code, message=f"{model_name}成功", data=data)
        else:
            return cls.error(message=f"{model_name}失败")

    @classmethod
    def result_bool(
        cls,
        *,
        data: Optional[Sequence[OutSchemaType]] | Optional[OutSchemaType] | bool = None,
        model_name: str = "",
        code: int = 200,
    ) -> ResultModel[bool]:
        if data is None or (
                type[data] == Optional[Sequence[OutSchemaType]] and len(data) == 0
        ):
            return cls.error(message=f"{model_name}失败")
        else:
            return cls.success(code=code, message=f"{model_name}成功", data=True)

    @classmethod
    def result_str(
        cls, *, data: str = None, model_name: str = "", code: int = 200
    ) -> ResultModel[str]:
        if data is not None:
            return cls.success(code=code, message=f"{model_name}成功", data=True)
        else:
            return cls.error(message=f"{model_name}失败")

    @classmethod
    def success(
        cls,
        *,
        data: Optional[
            OutSchemaType | Sequence[OutSchemaType] | PageModel[OutSchemaType] | bool | str
            ] = None,
        is_success: bool = True,
        message: str = "成功",
        code: int = 200,
    ) -> (
        ResultModel[Sequence[OutSchemaType]]
        | ResultModel[PageModel[OutSchemaType]]
        | ResultModel[OutSchemaType]
        | ResultModel[bool]
        | ResultModel[str]
    ):
        return ResultModel(is_success=is_success, code=code, message=message, data=data)

    @classmethod
    def error(
        cls, *, is_success: bool = False, message: str = "失败", code: int = 400
    ) -> ResultModel:
        return ResultModel(is_success=is_success, code=code, message=message)
